package cn.huapu.power.energy.util;


//import com.alibaba.fastjson.JSONArray;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @Author jzx
* @Description //转换工具
* @Date 9:11 2019-6-4
* @Param
* @return
**/
public final class ConvertUtil {
    public static final Map<String, Integer> NUM_MAP = new HashMap<>(20);
    /**
     * 围岩级别转换
     */
    public static final Map<String, Integer> LEVINE_NUMBER = new HashMap<>();

    /**
     * 数字提取正则
     */
    public static final Pattern pattern=Pattern.compile("[^0-9]");

    static {
        //日期
        NUM_MAP.put("日", -5);
        //掌子面
        NUM_MAP.put("掌", -4);
        NUM_MAP.put("零", 0);
        NUM_MAP.put("一", 1);
        NUM_MAP.put("二", 2);
        NUM_MAP.put("三", 3);
        NUM_MAP.put("四", 4);
        NUM_MAP.put("五", 5);
        NUM_MAP.put("六", 6);
        NUM_MAP.put("七", 7);
        NUM_MAP.put("八", 8);
        NUM_MAP.put("九", 9);
        NUM_MAP.put("左", 10);
        NUM_MAP.put("拱", 11);
        NUM_MAP.put("右", 12);
        NUM_MAP.put("上", 13);
        NUM_MAP.put("中", 14);
        NUM_MAP.put("下", 15);

        LEVINE_NUMBER.put("Ⅰ", 1);
        LEVINE_NUMBER.put("Ⅱ", 2);
        LEVINE_NUMBER.put("Ⅲ", 3);
        LEVINE_NUMBER.put("Ⅳ", 4);
        LEVINE_NUMBER.put("Ⅴ", 5);
        LEVINE_NUMBER.put("Ⅵ", 6);
    }



    /**
    * @Author jzx
    * @Description //把集合根据指定的键转换成map
    * @Date 9:11 2019-6-4
    * @Param [obj, key, value]
    * @return java.util.Map<java.lang.String,java.lang.Object>
    **/
    public static Map<String, Object> listConvertToMap(List obj, String key, String value) {
        if (obj == null || obj.size() == 0) {
            return new HashMap<>();
        }
        if (key == null || "".equals(key)) {
            return new HashMap<>();
        }
        if (value == null || "".equals(value)) {
            return new HashMap<>();
        }
        Map<String, Object> res = new HashMap<>();
        String resConvertKey;
        Object resConvertValue;
        try {
            //遍历集合然后根据需要转换的参数返回
            for (Object t : obj) {
                //根据泛型拿到需要转换的对象
                Class srcClass = t.getClass();
                Method methodKey = srcClass.getDeclaredMethod(getGetterByFiledName(key), null);
                resConvertKey = (String) methodKey.invoke(t, null);
                Method methodValue = srcClass.getDeclaredMethod(getGetterByFiledName(value), null);
                resConvertValue = methodValue.invoke(t, null);
                res.put(resConvertKey, resConvertValue);
            }
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
    * @Author jzx
    * @Description //获取get方法名
    * @Date 9:12 2019-6-4
    * @Param [str]
    * @return java.lang.String
    **/
    private static String getGetterByFiledName(String str) {
        return "get" + str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
    * @Author jzx
    * @Description //获取get方法名
    * @Date 9:12 2019-6-4
    * @Param [str]
    * @return java.lang.String
    **/
    private static String getSetterByFiledName(String str) {
        return "set" + str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
     * 将json字符串转换成Array
     * 或者将以,分割的字符串转换成Array
     *
     * @return
     */
    /*public static List<String> strToArray(String str) {
        if (ValidateUtil.strIsBlank(str)) {
            return null;
        }
        if (ValidateUtil.isJsonArray(str)) {
            return JSONArray.parseArray(str, String.class);
        }
        if (str.contains(",")) {
            return Arrays.asList(str.split(","));
        }
        ArrayList<String> list = new ArrayList<>();
        list.add(str);
        return list;
    }*/

    /**
     * 对象转map
     *
     * @param cls
     * @return
     */
    public static Map<String, Object> objToMap(Object cls) {
        Map<String, Object> map = null;
        try {
            Field[] fields = cls.getClass().getDeclaredFields();
            if (fields.length == 0) {
                return null;
            }
            map = new HashMap<>();
            for (int i = 0; i < fields.length; i++) {
                if (fields[i].getName().contains("$")) {
                    continue;
                }
                Method method = cls.getClass().getDeclaredMethod(getSetterByFiledName(fields[i].getName()), null);
                Object val = method.invoke(cls, null);
                map.put(fields[i].getName(), val);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 对象转map
     *
     * @param cls
     * @return
     */
    public static Map<String, Object> objToMap(Object cls, Class type) {
        if (cls == null) {
            return null;
        }
        String clsName = null;
        if (cls.getClass().getName().contains("$")) {
            clsName = cls.getClass().getName().substring(0, cls.getClass().getName().indexOf("$"));
        } else {
            clsName = cls.getClass().getName();
        }
        if (!clsName.equals(type.getName())) {
            return null;
        }
        Map<String, Object> map = null;
        try {
            Field[] fields = type.getDeclaredFields();
            if (fields.length == 0) {
                return null;
            }
            map = new HashMap<>(fields.length);
            for (int i = 0; i < fields.length; i++) {
                if (fields[i].getName().contains("$")) {
                    continue;
                }
                fields[i].setAccessible(true);
                map.put(fields[i].getName(), fields[i].get(cls));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 传入对象
     * @param obj
     * @param cls
     * @param <T> 这个是字段类型（int String....）
     * @param attributes 需要取值的对象
     * @return
     */
    public static <T>  T getValueByObjectAttributes(Object obj,String attributes,Class<T> cls){
        return getValueByObjectAttributes(obj,attributes,cls,null);
    }
    /**
     * 传入对象
     * @param obj
     * @param cls
     * @param <T>  默认值如果为空返回默认
     * @param attributes 需要取值的对象
     * @return
     */
    public static <T>  T getValueByObjectAttributes(Object obj,String attributes,Class<T> cls,T defValue){
        if(ValidateUtil.objIsNull(obj,attributes,cls)){
            return defValue;
        }
        try {
            Field field=obj.getClass().getDeclaredField(attributes);
            field.setAccessible(true);
            return (T)field.get(obj);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return defValue;
    }
    /**
     * 处理xml中特殊字符串 & > <
     *
     * @param cls
     * @return
     */
    public static void changeXmlSymbol(Object cls) {
        Field[] fields = cls.getClass().getDeclaredFields();
        if (fields.length == 0) {
            return;
        }
        for (int i = 0; i < fields.length; i++) {
            Method getMethod = null;
            try {
                getMethod = cls.getClass().getDeclaredMethod(getGetterByFiledName(fields[i].getName()), null);
                Method setMethod = cls.getClass().getDeclaredMethod(getSetterByFiledName(fields[i].getName()), String.class);
                Object val = getMethod.invoke(cls, null);
                if (val instanceof String) {
                    String oldStr = (String) val;
                    if (oldStr.contains("<")) {
                        setMethod.invoke(cls, oldStr.replace("<", "&lt;"));
                    }
                    if (oldStr.contains(">")) {
                        setMethod.invoke(cls, oldStr.replace(">", "&gt;"));
                    }
                    if (oldStr.contains("&")) {
                        setMethod.invoke(cls, oldStr.replace("&", "&amp;"));
                    }
                }
            } catch (Exception e) {
                continue;
            }
        }
    }

    /**
     * 将空白字符串转换成null
     *
     * @param cls
     */
    public static void changeEmptyStrToNull(Object cls) {
        Field[] fields = cls.getClass().getDeclaredFields();
        if (fields.length == 0) {
            return;
        }
        List<String> fieldStr = new ArrayList<>();
        try {
            for (int i = 0; i < fields.length; i++) {
                Method getStrMethod = cls.getClass().getDeclaredMethod(getGetterByFiledName(fields[i].getName()));
                Object val = getStrMethod.invoke(cls);
                //先判断是否是字符类型 因为字符要考虑为空白字符串的情况
                if (val instanceof String) {
                    if (ValidateUtil.strIsBlank((String) val)) {
                        fieldStr.add(fields[i].getName());
                    }
                }
            }
            if (fieldStr.size() == 0) {
                return;
            }
            String[] res = new String[fieldStr.size()];
            fieldStr.toArray(res);
            changeFiledToNull(cls, res);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将指定的字段设置为null
     *
     * @param cls
     */
    public static void changeFiledToNull(Object cls, String... fields) {
        if (fields.length == 0) {
            return;
        }
        for (String field : fields) {
            try {
                //获取域
                Field f = cls.getClass().getDeclaredField(field);
                Class fCls = f.getType();
                Method setMethod = cls.getClass().getDeclaredMethod(getSetterByFiledName(field), fCls);
                if (setMethod != null) {
                    setMethod.invoke(cls, new Object[]{null});
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 将字符串中的汉字数字转换成阿拉伯
     *
     * @param cn
     * @return
     */
    public static Integer ChineseToNumber(String cn) {
        if (ValidateUtil.strIsBlank(cn)) {
            return Integer.MAX_VALUE;
        }
        if (ValidateUtil.isNumber(cn)) {
            return Integer.valueOf(cn);
        }
        String[] chart = cn.split("");
        StringBuffer resBuffer = new StringBuffer();
        for (int i = 0; i < chart.length; i++) {
            if (NUM_MAP.containsKey(chart[i])) {
                resBuffer.append(NUM_MAP.get(chart[i]));
            }
        }
        if (resBuffer.length() == 0) {
            String num=extractingNumbers(cn);
            if(ValidateUtil.isNumber(num)){
                return Integer.parseInt(num)+letterToNumber(ChineseCharToEn.getAllFirstLetter(cn));
            }
            return letterToNumber(ChineseCharToEn.getAllFirstLetter(cn));
        }
        return Integer.valueOf(resBuffer.toString());
    }

    /**
     * 从字符串提取数字
     * @param str
     * @return
     */
    public static String extractingNumbers(String str) {
        if(ValidateUtil.strIsBlank(str)){
            return "";
        }
        Matcher a1 = pattern.matcher(str);
        String res = a1.replaceAll(" ");
        if(ValidateUtil.strIsBlank(res)){
            return "";
        }
        return  res.replace(" ","");
    }

    /**
     * 数字转字母 1-26 ： A-Z
     */
    private static String numberToLetter(int num) {
        if (num <= 0) {
            return null;
        }
        String letter = "";
        num--;
        do {
            if (letter.length() > 0) {
                num--;
            }
            letter = ((char) (num % 26 + (int) 'A')) + letter;
            num = (int) ((num - num % 26) / 26);
        } while (num > 0);

        return letter;
    }

    /**
     * 字母转数字  A-Z ：10000+( 1-26)
     *
     * @param letter
     * @return
     */
    private static int letterToNumber(String letter) {
        int length = letter.length();
        int num = 0;
        int number = 0;
        for (int i = 0; i < length; i++) {
            char ch = letter.charAt(length - i - 1);
            num = (int) (ch - 'A' + 1);
            num *= Math.pow(26, i);
            number += num;
        }
        return number+100;
    }

    /**
     * 获取对象的属性获取所有getter方法
     *
     * @return
     */
    public static List<Method> getObjectGetterMethods(Object obj) {
        if (obj == null) {
            return null;
        }
        //获取对象所有属性
        Field[] fields = obj.getClass().getDeclaredFields();
        if (fields.length == 0) {
            return null;
        }
        List<Method> methods = new ArrayList<>();
        for (int i = 0; i < fields.length; i++) {
            Field f = fields[i];
            try {
                methods.add(obj.getClass().getDeclaredMethod(getGetterByFiledName(f.getName())));
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return methods;
    }


    /**
     * 比较两个对象相同属性的值
     *
     * @param res
     * @param tar
     * @return
     */
    public static boolean comparObjSameField(Object res, Object tar) {
        if (ValidateUtil.objIsNull(res, tar)) {
            return false;
        }
        if (!res.getClass().equals(tar.getClass())) {
            return false;
        }
        //获取对象所有属性get方法
        List<Method> methods = getObjectGetterMethods(res);
        if (!ValidateUtil.listIsNull(methods)) {
            for (int i = 0; i < methods.size(); i++) {
                Method m = methods.get(i);
                try {
                    Object resVal = m.invoke(res);
                    Object tarVal = m.invoke(tar);
                    if (resVal != null && tarVal != null) {
                        if (!resVal.equals(tarVal)) {
                            return false;
                        }
                    }
                    if (resVal == null && tarVal != null) {
                        return false;
                    }
                    if (resVal != null && tarVal == null) {
                        return false;
                    }
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
            }
        }
        return true;
    }

    /**
     * 把map转换为 key 为String 值为obj形式
     *
     * @param map
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> Map<String, Object> convertMapToStrObj(Map<K, V> map) {
        if (ValidateUtil.mapIsNull(map)) {
            return null;
        }
        Map<String, Object> resMap = new LinkedHashMap<>();
        for (Map.Entry entry : map.entrySet()) {
            resMap.put((String) entry.getKey(), entry.getValue()==null?"/":entry.getValue());
        }
        return resMap;
    }
}
